package com.example.serviceheadlines.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.serviceheadlines.mapper.*;
import com.example.serviceheadlines.service.*;
import com.tangyuan.common.enums.HeadlinesCategoryEnum;
import com.tangyuan.common.exception.HeadlinesException;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.*;
import com.tangyuan.dto.HeadlineArticlePublishDto;
import com.tangyuan.dto.UpdateHeadlinesDto;
import com.tangyuan.model.*;
import com.tangyuan.model.headlines.HeadlinesCategoryQueryDto;
import com.tangyuan.model.headlines.HeadlinesContentQueryDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class HeadlinesServiceImpl extends ServiceImpl<HeadlinesMapper, Headlines> implements HeadlinesService {

    @Autowired
    private HeadlinesImagesService headlinesImagesService;
    @Autowired
    private HeadlinesImagesMapper headlinesImagesMapper;
    @Autowired
    private HeadlinesCommentMapper headlinesCommentMapper;
    @Autowired
    private IHeadlinesThumpService headlinesThumpService;
    @Autowired
    private IUserHeadlinesCollectionService iUserHeadlinesCollectionService;
    @Autowired
    private HeadlinesCategoryService headlinesCategoryService;


    /**
     * 单条查询百家数据
     * @param headlinesId 百家ID
     * @param userId 用户ID
     * @return 百家
     */
    @Override
    public Headlines getHeadlinesById(Long headlinesId, Long userId) {
        if(headlinesId == null || headlinesId == 0){
            return null;
        }
        Headlines headlines = baseMapper.selectById(headlinesId);
        if(headlines == null){
            return null;
        }
        List<Headlines> headlinesList = setHeadlinesImages(null,Collections.singletonList(headlines));
        if(CollectionUtils.isEmpty(headlinesList)){
            return null;
        }
        return headlinesList.get(0);
    }

    /**
     * 百家浏览量增加
     * @param headlinesId 百家ID
     */
    @Override
    public void browseHeadlines(Long headlinesId) {
        Headlines headlines = baseMapper.selectById(headlinesId);
        if (headlines == null) {
            log.error("百家数据不存在,ID:{}",headlinesId);
        }
        baseMapper.update(null ,new LambdaUpdateWrapper<Headlines>()
                .set(Headlines::getReadNum,headlines.getReadNum()+1)
                .eq(Headlines::getId,headlinesId));
    }

    /**
     * 分类分页查询百家数据
     * @param userId 用户Id
     * @param dto 分类
     * @return 百家
     */
    @Override
    public Page<Headlines> getHeadlinesList(Long userId, HeadlinesCategoryQueryDto dto) {
        Page<Headlines> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        List<Long> ids = null;
        switch (HeadlinesCategoryEnum.getHeadlinesCategoryEnum(dto.getCategoryId())){
            case RECOMMEND:
                ids = baseMapper.getHeadlinesId(page,null);
                break;
            case FOLLOW:
                ids = baseMapper.getConcernHeadlinesId(page,userId);
                break;
            default:
                ids = baseMapper.getHeadlinesId(page,dto.getCategoryId());
                break;
        }
        List<Headlines> list = getHeadlinesByIds(ids,userId);
        return page.setRecords(setHeadlinesImages(ids,list));
    }

    /**
     * 根据标题搜索分页数据
     * @param userId 用户Id
     * @param dto 标题
     * @return 百家
     */
    @Override
    public Page<Headlines> searchHeadlines(Long userId,HeadlinesContentQueryDto dto) {
        Page<Headlines> page = new Page<>(dto.getPageNum(),dto.getPageSize());
        List<Long> ids = baseMapper.searchHeadlinesId(page,dto.getSearchContent());
        if(CollectionUtils.isEmpty(ids)){
            return page;
        }
        List<Headlines> list = getHeadlinesByIds(ids,userId);
        return page.setRecords(setHeadlinesImages(ids,list));
    }


    /**
     * 设置百家数据的图片信息
     * @param list 百家数据
     * @param ids 排序规则(非必填)
     * @return 设置后的百家数据
     */
    private List<Headlines> setHeadlinesImages(List<Long> ids,List<Headlines> list){
        if(CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        List<Long> itemIds = list.stream().filter(item -> item.getType() == 1).map(Headlines::getId).collect(Collectors.toList());
        List<HeadlinesImages> images = new ArrayList<>();
        //images = 百家list集合中图文
        if(!CollectionUtils.isEmpty(itemIds)){
            images = baseMapper.getHeadlinesImagesByItemId(itemIds);
        }
        //set到对应的百家数据中
        List<Headlines> headlinesImages = HeadlinesImageUtil.packagingImage(list, images);
        if(CollectionUtils.isEmpty(ids)){
            return headlinesImages;
        }
        //根据 ids排序
        List<Headlines> headlinesList = new ArrayList<>();
        Map<Long, Headlines> collect = headlinesImages.stream().collect(Collectors.toMap(Headlines::getId, headline -> headline));
        for (Long headlines : ids) {
            if(collect.containsKey(headlines)){
                headlinesList.add(collect.get(headlines));
            }
        }
        return headlinesList;
    }

    @Override
    public Result headlinePublish(String token, HeadlineArticlePublishDto headlineArticlePublishDto) {
        List<MultipartFile> arrayList = new ArrayList<>();
        MultipartFile file = headlineArticlePublishDto.getFile();
        if (file != null){
            arrayList.add(file);
        }
        MultipartFile file2 = headlineArticlePublishDto.getFile2();
        if (file2 != null){
            arrayList.add(file2);
        }
        MultipartFile file3 = headlineArticlePublishDto.getFile3();
        if (file3 != null){
            arrayList.add(file3);
        }

        List<String> arrayList1 = new ArrayList<>();
        String articleUrl0 = headlineArticlePublishDto.getArticleUrl0();
        if (StringUtils.isNotEmpty(articleUrl0)){
            arrayList1.add(articleUrl0);
        }
        String articleUrl1 = headlineArticlePublishDto.getArticleUrl1();
        if (StringUtils.isNotEmpty(articleUrl1)){
            arrayList1.add(articleUrl1);
        }
        String articleUrl2 = headlineArticlePublishDto.getArticleUrl2();
        if (StringUtils.isNotEmpty(articleUrl2)){
            arrayList1.add(articleUrl2);
        }

        User user = CommStatus.getUser(token);
        // 限制只有超管才能发布百家中的唐园景区导游栏目 2024/8/15 下午 14:30 By 少帅
        usersNotPermissionPublishGuides(headlineArticlePublishDto.getCategoryId(), user);
        List<String> urlList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(arrayList)){
            //调用阿里OSS上传头像 获取头像url
            for (MultipartFile multipartFile : arrayList){
                if(multipartFile.isEmpty()){
                    continue;
                }
                urlList.add(PictureOSSUtils.upload(multipartFile, FileNameUtil.getPngName())) ;
            }
        }

        for (String s : arrayList1){
            if (StringUtils.isNotEmpty(s)){{
                urlList.add(s);
            }}
        }
        Headlines headlines = packagingHeadlines(headlineArticlePublishDto.getCategoryId(), null, headlineArticlePublishDto.getTitle(), headlineArticlePublishDto.getContent(), "", 1, user);
        baseMapper.insert(headlines);
        headlinesImagesService.insertImages(urlList,headlines.getId());
        //唐园景区导游
        if(headlineArticlePublishDto.getCategoryId().equals(14L)){
            PushAppUtil.pushInform("唐园视频",headlines.getTitle());
        }
        return Result.ok();
    }

    @Override
    public Result headlineVideoPublish(String token, Long categoryId, String area, String title, MultipartFile file,MultipartFile file1,String videoUrl,String videoFirstImageUrl) {

        // 视频标题字数在5-30字 2024/5/18 9:54 By 少帅
        if (title.length() <5 || title.length() > 30){
            return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        User user = CommStatus.getUser(token);
        // 限制只有超管才能发布百家中的唐园景区导游栏目 2024/8/15 下午 14:30 By 少帅
        usersNotPermissionPublishGuides(categoryId, user);
        //上传视频到阿里
        if (videoUrl == null){
            videoUrl= VideoOSSUtils.upload(file, FileNameUtil.getMp4Name());
        }
        if (videoFirstImageUrl == null){
            videoFirstImageUrl = PictureOSSUtils.upload(file1, FileNameUtil.getPngName());
        }

        Headlines headlines = packagingHeadlines(categoryId, area, title,  videoUrl, videoFirstImageUrl,2, user);
        baseMapper.insert(headlines);
        return Result.ok();
    }

    private void usersNotPermissionPublishGuides(Long categoryId, User user) {
        Long headlinesCategoryId = headlinesCategoryService.getHeadlinesCategoryByChannelName("唐园景区导游");
        if (Objects.equals(categoryId,headlinesCategoryId)){
            if (user != null && user.getAdminFlag() != 1) {
                throw new HeadlinesException(ResultCodeEnum.NO_HEADLINES_PERMISSIONS);
            }
        }
    }

    @Override
    public Result deleteHeadlinesById(String token, Long headlinesId) {
        User user = CommStatus.getUser(token);
        if (user == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_AUTH);
        }
        if (headlinesId == null) {
            return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        Headlines headlines = baseMapper.selectById(headlinesId);
        if (headlines == null) {
            return Result.build(null, ResultCodeEnum.NO_SEARCH_DATA);
        }
        if (headlines.getType() == null) {
            return Result.build(null, ResultCodeEnum.DATA_ERROR);
        }
        if (!headlines.getUserId().equals(user.getId())) {
            return Result.build(null, ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }
        if (headlines.getType() == 1) {
            List<String> imageList = headlinesImagesMapper.selectImageList(headlinesId);
            if (!CollectionUtils.isEmpty(imageList)) {
                for (String image : imageList) {
                    PictureOSSUtils.delOssFile(image);
                }
                headlinesImagesMapper.deleteByHeadlinesId(headlinesId);
            }

            deleteHeadlinesInvolve(headlinesId);

            return Result.ok();

        } else if (headlines.getType() == 2) {
            if (headlines.getImages() != null) {
                PictureOSSUtils.delOssFile(headlines.getImages());
            }
            if (headlines.getContent() != null) {
                VideoOSSUtils.delOssFile(headlines.getContent());
            }
            deleteHeadlinesInvolve(headlinesId);

            return Result.ok();
        }

        return Result.build(null, ResultCodeEnum.DATA_ERROR);

    }

    private void deleteHeadlinesInvolve(Long headlinesId) {
        baseMapper.deleteById(headlinesId);
        headlinesCommentMapper.delete(new LambdaQueryWrapper<HeadlinesComment>().eq(HeadlinesComment::getHeadlinesId, headlinesId));
        headlinesThumpService.deleteHeadlines(Collections.singletonList(headlinesId));
        iUserHeadlinesCollectionService.deleteHeadlines(Collections.singletonList(headlinesId));
    }


    private Headlines packagingHeadlines(Long categoryId, String area, String title, String content, String videoFirstImageUrl, Integer type, User user){
        Headlines headlines = new Headlines();
        headlines.setCategoryId(categoryId);
        headlines.setImages(StringUtils.isNotEmpty(videoFirstImageUrl) ? videoFirstImageUrl : null);
        headlines.setTitle(title);
        headlines.setType(type);
        headlines.setContent(content);
        headlines.setMediaInfoName(user.getName());
        headlines.setAvatarUrl(user.getHeadImage());
        headlines.setUserId(user.getId());
        headlines.setPublishTime(new Date());
        headlines.setCreateTime(new Date());
        headlines.setArea(area);
        return headlines;
    }
    private List<Headlines> getHeadlinesByIds(List<Long> ids,Long userId){
        if(CollectionUtils.isEmpty(ids)){
            return new ArrayList<>();
        }
        return baseMapper.getHeadlinesByIds(ids,userId);
    }


    /**
     * 分页获取我发布的百家数据
     * @param userId 用户Id
     * @return 百家
     */
    @Override
    public List<Headlines> getMyHeadlinesByUserId(Long userId, Integer pageNum, Integer pageSize) {
        QueryWrapper<Headlines> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Headlines::getUserId,userId);
        wrapper.lambda().orderByDesc(Headlines::getCreateTime);
        Page<Headlines> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
        if(CollectionUtils.isEmpty(page.getRecords())){
            return new ArrayList<>();
        }
        List<Long> ids = page.getRecords().stream().map(Headlines::getId).collect(Collectors.toList());
        List<Headlines> headlinesList = getHeadlinesByIds(ids, userId);
        return setHeadlinesImages(ids,headlinesList);
    }

    /**
     * 获取我发布百家数据获得的点赞数
     * @param userId
     * @return
     */
    @Override
    public Long getArticleThumpNumByUserId(Long userId) {
        return baseMapper.getArticleThumpNumByUserId(userId);
    }


    /**
     * 分页获取我点赞的百家
     * @param userId 用户Id
     */
    @Override
    public List<Headlines> getMyTrumpHeadlines(Long userId, Integer pageNum, Integer pageSize) {
        List<HeadlinesThump> headlines = headlinesThumpService.getMyTrumpHeadlines(userId, pageNum, pageSize);
        if(CollectionUtils.isEmpty(headlines)){
            return new ArrayList<>();
        }
        List<Long> ids = headlines.stream().map(HeadlinesThump::getAId).collect(Collectors.toList());
        List<Headlines> headlinesList = getHeadlinesByIds(ids, userId);
        return setHeadlinesImages(ids,headlinesList);
    }

    /**
     * 分页获取我收藏的百家
     * @param userId 用户
     */
    @Override
    public List<Headlines> getMyCollectArticle(Long userId, Integer pageNum, Integer pageSize) {
        List<UserHeadlinesCollection> headlines = iUserHeadlinesCollectionService.getMyCollectArticle(userId, pageNum, pageSize);
        if(CollectionUtils.isEmpty(headlines)){
            return new ArrayList<>();
        }
        List<Long> ids = headlines.stream().map(UserHeadlinesCollection::getHeadlinesId).collect(Collectors.toList());
        List<Headlines> headlinesList = getHeadlinesByIds(ids, userId);
        return setHeadlinesImages(ids,headlinesList);
    }



    /**
     * 修改百家数据的用户名和头像
     * @param dto 用户名或头像(必填其一)
     */
    @Override
    public void updateHeadlinesUserMessage(UpdateHeadlinesDto dto) {
        if(dto == null ||
            (dto.getUserId() == null || dto.getUserId() == 0) ||
            (StringUtils.isEmpty(dto.getNickName()) && StringUtils.isEmpty(dto.getUrl()))){
            log.error("百家修改参数不可为空");
            return;
        }
        baseMapper.update(null,new LambdaUpdateWrapper<Headlines>()
                .eq(Headlines::getUserId,dto.getUserId())
                .set(!StringUtils.isEmpty(dto.getUrl()),Headlines::getAvatarUrl,dto.getUrl())
                .set(!StringUtils.isEmpty(dto.getNickName()),Headlines::getMediaInfoName,dto.getNickName())
        );
    }


    /**
     * 随机查询非今日头条并且点赞数小于200的十条数据
     * @return List<Headlines>
     */
    @Override
    public List<Headlines> getMediaEqualToNullData(){
        QueryWrapper<Headlines> wrapper = new QueryWrapper<>();
        wrapper.lambda().isNull(Headlines::getMediaId);
        wrapper.lambda().le(Headlines::getThumpUpNum,200);
        wrapper.orderByAsc("RAND()");
        wrapper.last("limit 10");
        return baseMapper.selectList(wrapper);
    }

    @Override
    public Headlines getPushHeadlines(Date date) {
        return baseMapper.getPushHeadlines(date);
    }
}
